/*
*********************************************************************************************************
*
*	模块名称 : USART调试串口驱动模块
*	文件名称 : bsp_usart.c
*	版    本 : V1.0
*	说    明 : 调试串口重定向
*
*	修改记录 :
*		版本号  日期        作者     说明
*		V1.0    2024-12-06 astronG  正式发布
*
*	Copyright (C), 2015-2030, astronG
*
*********************************************************************************************************
*/

#include "bsp.h"
#include "usart.h"



uint16_t dma_last_pos = 0;
//static volatile uint16_t dma_current_pos = 0;
uint16_t dma_current_pos = 0;
uint8_t uart_rx_buffer[UART_RX_BUFFER_SIZE];


/*
*********************************************************************************************************
*	函 数 名: debug_print
*	功能说明: 格式化并通过UART发送调试信息。该函数接受一个格式化字符串和可变数量的参数，
*            将它们格式化为一个字符串，然后通过UART发送出去。
*	形    参：
*           fmt: 格式化字符串，类似于printf的格式。
*           ...: 可变数量的参数，与fmt中的格式说明符对应。
*	返 回 值: 无
* 注意事项：传入参数不要超过255个字节，否则会导致数据丢失。
*						本函数进行了线程安全保护。(不要在中断调用本函数)
*********************************************************************************************************
*/
void debug_print(const char *const fmt, ...)
{
    char str[256];
    uint16_t len;
    va_list args;
    memset(str, 0, sizeof(str));
    va_start(args, fmt);
    vsnprintf(str, 255, fmt, args);
    va_end(args);
    len = strlen(str);
    // 获取互斥锁，保护串口资源
    xSemaphoreTake(xUartMutex, portMAX_DELAY);
    HAL_UART_Transmit_DMA(&huart1, (uint8_t *)str, len);
    // 等待发送完成信号量
    xSemaphoreTake(xTxSemaphore, portMAX_DELAY);
    // 释放互斥锁
    xSemaphoreGive(xUartMutex);
    //    if(xSemaphoreTake(xUartMutex, pdMS_TO_TICKS(100))) {
    //        // 等待DMA空闲
    //        if(xSemaphoreTake(xTxSemaphore, pdMS_TO_TICKS(100))) {
    //            HAL_UART_Transmit_DMA(&huart3, (uint8_t*)str, len);
    //        } else {
    //            // 超时处理
    //        }
    //        xSemaphoreGive(xUartMutex);
    //    }
}

/*
*********************************************************************************************************
*	函 数 名: HAL_UART_TxCpltCallback
*	功能说明: UART发送完成回调函数
*	形    参：
*           huart: UART句柄
*	返 回 值: 无
*********************************************************************************************************
*/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART3) {
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;
        // 释放发送完成信号量
        xSemaphoreGiveFromISR(xTxSemaphore, &xHigherPriorityTaskWoken);
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
}



/*
*********************************************************************************************************
*	函 数 名: UART_IdleHandler
*	功能说明: 串口空闲中断处理函数
*	形    参: huart - 串口句柄
*	返 回 值: 无
*********************************************************************************************************
*/
void UART_IdleHandler(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART3) {
        __HAL_UART_CLEAR_IDLEFLAG(huart); // 清除空闲中断标志
        // 记录当前DMA位置
        dma_current_pos = UART_RX_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx);
        // 释放信号量通知任务有数据到达
        xSemaphoreGiveFromISR(xUartRxSemaphore, NULL);
    }
}

/*
*********************************************************************************************************
*	函 数 名: ProcessUartData
*	功能说明: 处理接收到的串口数据，检测帧头帧尾
*	形    参: start_index - 数据起始索引
*           length - 数据长度
*	返 回 值: 无
*********************************************************************************************************
*/
void ProcessUartData(uint16_t start_index, uint16_t length)
{
    static FrameState frame_state = FRAME_STATE_IDLE;
    static uint16_t frame_length = 0;
    static UartFrame frame;  // 静态帧结构体

    for (uint16_t i = 0; i < length; i++) {
        uint16_t buffer_index = (start_index + i) % UART_RX_BUFFER_SIZE;
        uint8_t data_byte = uart_rx_buffer[buffer_index];

        // 检查缓冲区溢出
        if (frame_length >= UART_MAX_FRAME_SIZE) {
            frame_state = FRAME_STATE_IDLE;
            frame_length = 0;
            memset(&frame, 0, sizeof(UartFrame));
            continue;
        }

        // 存储所有字节（包括帧头和帧尾）
        frame.data[frame_length++] = data_byte;

        // 状态机处理
        switch (frame_state) {
        case FRAME_STATE_IDLE:
            if (data_byte == FRAME_HEADER_1) {
                frame_state = FRAME_STATE_HEADER_1;
            }

            break;

        case FRAME_STATE_HEADER_1:
            frame_state = (data_byte == FRAME_HEADER_2) ?
                          FRAME_STATE_HEADER_2 : FRAME_STATE_IDLE;
            break;

        case FRAME_STATE_HEADER_2:
            frame_state = (data_byte == FRAME_HEADER_3) ?
                          FRAME_STATE_HEADER_3 : FRAME_STATE_IDLE;
            break;

        case FRAME_STATE_HEADER_3:
            frame_state = (data_byte == FRAME_HEADER_4) ?
                          FRAME_STATE_DATA : FRAME_STATE_IDLE;
            break;

        case FRAME_STATE_DATA:
            if (data_byte == FRAME_FOOTER_1) {
                frame_state = FRAME_STATE_FOOTER_1;
            }

            break;

        case FRAME_STATE_FOOTER_1:
            frame_state = (data_byte == FRAME_FOOTER_2) ?
                          FRAME_STATE_FOOTER_2 : FRAME_STATE_DATA;
            break;

        case FRAME_STATE_FOOTER_2:
            frame_state = (data_byte == FRAME_FOOTER_3) ?
                          FRAME_STATE_FOOTER_3 : FRAME_STATE_DATA;
            break;

        case FRAME_STATE_FOOTER_3:
            if (data_byte == FRAME_FOOTER_4) {
                // 完整帧接收完成
                frame.length = frame_length;

                // 将帧发送到队列
                if (xQueueSend(xUartFrameQueue, &frame, 0) != pdTRUE) {
                    debug_print("Frame queue full, frame discarded\r\n");
                }
            }

            // 无论是否完成，重置状态机
            frame_state = FRAME_STATE_IDLE;
            frame_length = 0;
            memset(&frame, 0, sizeof(UartFrame));
            break;

        default:
            frame_state = FRAME_STATE_IDLE;
            frame_length = 0;
            memset(&frame, 0, sizeof(UartFrame));
            break;
        }

        // 状态错误时重置
        if (frame_state == FRAME_STATE_IDLE && frame_length > 0) {
            frame_length = 0;
            memset(&frame, 0, sizeof(UartFrame));
        }
    }
}

/*
*********************************************************************************************************
*	函 数 名: ProcessUartFrame
*	功能说明: 处理完整的串口帧
*	形    参: frame - 帧数据
*	返 回 值: 无
*********************************************************************************************************
*/
void ProcessUartFrame(UartFrame *frame)
{
    // 检查最小帧长度（头4 + 尾4 = 8字节）
    if (frame->length < 12) {
        debug_print("Frame too short\r\n");
        return;
    }

    // 验证帧头帧尾
    if (frame->data[0] != FRAME_HEADER_1 ||
            frame->data[1] != FRAME_HEADER_2 ||
            frame->data[2] != FRAME_HEADER_3 ||
            frame->data[3] != FRAME_HEADER_4) {
        debug_print("Invalid header\r\n");
        return;
    }

    uint8_t footer_start = frame->length - 4;

    if (frame->data[footer_start] != FRAME_FOOTER_1 ||
            frame->data[footer_start + 1] != FRAME_FOOTER_2 ||
            frame->data[footer_start + 2] != FRAME_FOOTER_3 ||
            frame->data[footer_start + 3] != FRAME_FOOTER_4) {
        debug_print("Invalid footer\r\n");
        return;
    }

    // 提取指令部分（去掉头尾）	55 AA 55 AA FF A1 00 30 FA E9 16 E9 16 E9
    uint8_t address = frame->data[4];  // 指令类型
    uint8_t subcmd = frame->data[5]; // 子指令
    uint16_t data1 = (frame->data[6] << 8) | frame->data[7]; // 数据
    UartFrame response;

    // 指令处理
    switch (address) {
    case 0xFF:  // 示例指令
        switch (subcmd) {
        case 0xA1:


            // 构建响应帧
            response.data[0] = FRAME_HEADER_1;
            response.data[1] = FRAME_HEADER_2;
            response.data[2] = FRAME_HEADER_3;
            response.data[3] = FRAME_HEADER_4;
            response.data[4] = 0xFF;  // 响应类型
            response.data[5] = 0xB1;  // 响应代码
            response.data[6] = data1 >> 8;  // 高位
            response.data[7] = data1 & 0xFF; // 低位
            response.data[8] = FRAME_FOOTER_1;
            response.data[9] = FRAME_FOOTER_2;
            response.data[10] = FRAME_FOOTER_3;
            response.data[11] = FRAME_FOOTER_4;
            response.length = 12;
            SafeUartTransmit(response.data, response.length);
            break;

        case 0xA2:


            // 构建响应帧
            response.data[0] = FRAME_HEADER_1;
            response.data[1] = FRAME_HEADER_2;
            response.data[2] = FRAME_HEADER_3;
            response.data[3] = FRAME_HEADER_4;
            response.data[4] = 0xFF;  // 响应类型
            response.data[5] = 0xB2;  // 响应代码
            response.data[6] = data1 >> 8;  // 高位
            response.data[7] = data1 & 0xFF; // 低位
            response.data[8] = FRAME_FOOTER_1;
            response.data[9] = FRAME_FOOTER_2;
            response.data[10] = FRAME_FOOTER_3;
            response.data[11] = FRAME_FOOTER_4;
            response.length = 12;
            SafeUartTransmit(response.data, response.length);
            break;			
			
			
        default:
            debug_print("Unknown subcmd: %02X\r\n", subcmd);
            break;
        }

        break;

    default:
        debug_print("Unknown address: %02X\r\n", address);
        break;
    }
}

// 安全发送函数
void SafeUartTransmit(uint8_t *data, uint16_t length)
{
    if (xSemaphoreTake(xUartMutex, pdMS_TO_TICKS(50))) {
        //        if(xSemaphoreTake(xTxSemaphore, pdMS_TO_TICKS(50)) == pdTRUE) {
        //            HAL_UART_Transmit_DMA(&huart3, data, length);
        //        }
        HAL_UART_Transmit_DMA(&huart1, data, length);
        xSemaphoreGive(xUartMutex);
    }
}

